package ChatNI;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import Controller.ChatController;
import Controller.User;

public class ChatNI {
	final static int portudp = 9876;
	final static int porttcp = 6789;
	private boolean connected;
	private ChatController controller;
	private UDPSender udpSender;
	private UDPServer udpServer;
	private TCPServer tcpsrv;
	private TCPSender tcpsender;


	/**
	 * Initialize the attributes and start the TcpServer and UdpServer
	 * @param ChatController Controller du ChatSystem
	 */
	public ChatNI(ChatController controller){
		connected = true;
		this.controller = controller;
		//on cree et lance le server
		udpServer = new UDPServer(this); 
		udpServer.start();
		udpSender = new UDPSender(this);
		tcpsrv = new TCPServer((this));
		tcpsrv.start();
	}

	//public void setChatController(ChatController controller){
	//	this.controller = controller;
	//}


	/***
	 * 
	 * SEND METHODS
	 * 
	 */


	/**
	 * Tell the UDPSender to send a Hello Signal
	 */
	public void sendHello() {
		udpSender.sendHello();
	}


	/**
	 * Tell the UDPSender to send a HelloAck Signal
	 *  @param user The User to which we want to send the HelloAck
	 */
	public void sendHelloAck(User user) {
		udpSender.sendHelloAck(user);
	}

	/**
	 * Tell the UDPSender to send a TextMessage Signal
	 *  @param msg The message the user want to send
	 *  @param dest The list of User to which we want to send the TextMessage
	 */
	public void sendTextMessage(String msg, List<User> dest){	
		udpSender.sendTextMessage(msg, dest);
	}


	/**
	 * Create and tell the TCPSender to send a file
	 * @param file The file we want to send 
	 * @param dest The list of User to which we want to send the TextMessage
	 * @param u  The User to which we want to send the file at the moment
	 */
	public void sendFile(File file,List<User> dest, User u){
		tcpsender = new TCPSender(file, dest, this, u);
		tcpsender.start();
	}

	/**
	 * Tell the UDPSender to send a Goodbye Signal
	 */
	public void sendGoodbye(){
		udpSender.sendGoodbye();
		closeSystem(); 
	}

	public void closeSystem() {
		try {
			tcpsrv.getServerSocket().close();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		this.connected = false;
		tcpsrv.interrupt();
		System.out.println("Connected = FALSE");

		if (tcpsender != null) {
			this.tcpsender.interrupt();
		}
	}

	/***
	 * 
	 * PROCESS METHODS
	 * 
	 */


	/**
	 * Process Hello to the controller
	 * @param user The User we received the Hello from
	 */
	public void processHello(User user) {
		controller.processHello(user);
	}

	/**
	 * Process HelloAck to the controller
	 * @param user The User we received the HelloAck from
	 */
	public void processHelloAck(User user) {
		controller.processHelloAck(user);
	}


	/**
	 * Process TextMessage to the controller
	 * @param user The User we received the Message from
	 * @param msg The message we received from the user 
	 * @param dest The list of User the TextMessage was send to
	 */
	public void processTextMessage(User srcUser, String msg, ArrayList<User> dest){
		controller.processTextMessage(srcUser, msg, dest);
	}


	/**
	 * Process FileMessage to the controller
	 * @param user The User we received the File from
	 * @param fileName The name of the file we received from the user 
	 * @param dest The list of User the FileMessage was send to
	 */
	public void processFileMessage(User user, String fileName, ArrayList<User> dest){
		controller.processFileMessage(user, fileName, dest);
	}



	/**
	 * Process Goodbye to the controller
	 * @param user The User we received the Goodbye from
	 */
	public void processGoodbye(User user) {
		controller.processGoodbye(user);
	}

	/**
	 * Process if an error occur during the file transfert to the controller
	 * @param fileName The name of the file we tried to send 
	 * @param dest The list of User the FileMessage was supposed to be send
	 */
	public void processFileError(String fileName, List<User> dests){
		controller.processFileError(fileName, dests);
	}
	/***
	 * 
	 * SETTERS & GETTERS
	 * 
	 */

	/**
	 * return the value of the current user from the controller
	 * @return Return the localUser
	 */
	public User getLocalUser(){
		return controller.getLocalUser();
	}

	/**
	 * @return Return if the localuser is connect or not 
	 */
	public boolean isConnected() {
		return connected;
	}

	/**
	 * Set the boolean connected 
	 */
	public void setConnected(boolean connected) {
		this.connected = connected;
	}

}
